#include "Camera.h"

//Pinhole camera 

//Constructor
//Initialize the pinhole camera with the required values
PHCamera::PHCamera(Vector3 pos, Vector3 lookat, Vector3 up, Handedness hand, float focus, float iwidth, float iheight)
{
	this->position = pos;
	this->direction = lookat;
	this->up = up;
	this->hand = hand;
	this->focal_length = focus;

	//now for the camera's coord system
	//Left handed camera coords
	if(hand == LHS)
		this->camera_coord.w = direction;
	else if(hand == RHS)
		this->camera_coord.w = -direction;
	//normalize the camera_coord look at 
	//We use the same direction because in LHS, look direction is into the scene - essentially like the Z axis
	camera_coord.w.Normalize();
		
	//now get the left axis of camera
	camera_coord.u = up ^ camera_coord.w;
	camera_coord.u.Normalize();
	//now get the up axis for camera coords
	camera_coord.v = camera_coord.w ^ camera_coord.u;

	//Image plane
	//analagous to the film in camera
	//focal length is the the distance between between pinhole and the image ie Camera position and image plane
	//the bigger the image plane, the the bigger the image will be

	//image planes width, and height required
	image_width = iwidth;
	image_height = iheight;
	
	//assuming view direction is in the middle of the image plane
	image_u = camera_coord.u;
	image_v = camera_coord.v;
	if(hand == LHS)
		image_o = Vector3(this->position.x - image_width/2, this->position.y - image_width/2, this->position.z - focal_length);
	else if(hand == RHS)
		image_o = Vector3(this->position.x - image_width/2, this->position.y - image_width/2, this->position.z + focal_length);
}


//Get a ray for a current pixel position
Ray3 PHCamera::GetRay(float pixel_x, float pixel_y)
{
	Vector3 torigin = pixel_x*image_u + pixel_y*image_v + image_o;
	Vector3 tdirection = this->position - torigin;
	tdirection.Normalize();
	return Ray3(torigin, tdirection);
}

